<?php

namespace app\common\service;

use think\exception\HttpResponseException;
use think\Response;
use think\response\Json;

/**
 * 接口统一响应的方式
 */
class JsonService
{
    /**
     * 返回结果
     * @param int $code 业务状态码
     * @param string $msg 提示信息
     * @param mixed $data 响应数据
     * @param int $httpStatus http状态码
     * @return Json
     */
    public static function result(int $code = 1, string $msg = 'ok', mixed $data = [], int $httpStatus = 200): Json
    {
        $data = self::formatData($data);
        $return = compact('code', 'msg', 'data');
        return json($return, $httpStatus);
    }

    /**
     * 成功
     * @param string $msg
     * @param mixed $data
     * @param int $code
     * @return Json
     */
    public static function success(string $msg = 'ok', mixed $data = [], int $code = 1): Json
    {
        return self::result($code, $msg, $data);
    }

    /**
     * 失败
     * @param string $msg
     * @param int $code
     * @param mixed $data
     * @return Json
     */
    public static function error(string $msg = 'error', int $code = 0, mixed $data = []): Json
    {
        return self::result($code, $msg, $data);
    }

    /**
     * 响应数据
     * @param mixed $data
     * @return Json
     */
    public static function data(mixed $data = []): Json
    {
        return self::success('ok', $data);
    }

    /**
     * 抛出异常
     * @param string $msg 错误提示
     * @param int $code 错误码
     * @param mixed $data 响应数据
     * @return Json
     */
    public static function throw(string $msg = 'error', int $code = 0, mixed $data = []): Json
    {
        $data = compact('code', 'msg', 'data');
        $response = Response::create($data, 'json');
        throw new HttpResponseException($response);
    }

    /**
     * 抛出未登录异常
     * @param string $msg 提示信息
     * @return void
     */
    public static function notLoginError(string $msg = '还未登录'): void
    {
        self::throw($msg, 401);
    }

    /**
     * 格式化转换响应的数据
     * @param $data
     * @return mixed
     */
    private static function formatData($data): mixed
    {
        if ($data instanceof \think\Model || $data instanceof \think\Collection) {
            return $data->toArray();
        }
        return $data;
    }
}